<!-- src/components/MarkdownRenderer.vue -->
<template>
  <div class="markdown-content">
    <div v-html="renderedContent"></div>
  </div>
</template>

<script setup lang="ts">
import MarkdownIt from 'markdown-it'
import hljs from 'highlight.js'
import Clipboard from 'clipboard'
import { computed, onMounted, nextTick, watch } from 'vue'
import 'highlight.js/styles/atom-one-dark.css'
import dayjs from 'dayjs'

// 扩展 Window 接口
declare global {
  interface Window {
    downloadCode?: (code: string, lang: string) => void;
  }
}

const props = defineProps<{
  content: string
}>()

// 下载代码函数
const downloadCode = (code: string, lang: string) => {
  const blob = new Blob([code], { type: 'text/plain' })
  const url = window.URL.createObjectURL(blob)
  const a = document.createElement('a')
  const timestamp = new Date().getTime()
  let extension = lang || 'txt'
  
  // 根据语言确定文件扩展名
  switch (lang.toLowerCase()) {
    case 'javascript':
    case 'js':
      extension = 'js'
      break
    case 'typescript':
    case 'ts':
      extension = 'ts'
      break
    case 'html':
      extension = 'html'
      break
    case 'css':
      extension = 'css'
      break
    case 'scss':
      extension = 'scss'
      break
    case 'json':
      extension = 'json'
      break
    case 'vue':
      extension = 'vue'
      break
    // 可以添加更多语言类型
  }

  a.href = url
  a.download = `vivian_gpt_${dayjs(timestamp).format('YYYYMMDD')}.${extension}`
  document.body.appendChild(a)
  a.click()
  window.URL.revokeObjectURL(url)
  document.body.removeChild(a)
}

// 初始化 markdown-it
const md: MarkdownIt = new MarkdownIt({
  html: true,
  linkify: true,
  typographer: true,
  highlight: function (str: string, lang: string): string {
    if (lang && hljs.getLanguage(lang)) {
      try {
        const highlighted = hljs.highlight(str, { language: lang }).value
        const id = `code-${Math.random().toString(36).substring(2)}`
        
        // 将原始代码存储到全局变量中
        setTimeout(() => {
          const codeBlock = document.getElementById(id)
          if (codeBlock) {
            // 使用 base64 编码存储代码内容，避免 HTML 转义问题
            codeBlock.setAttribute('data-code', btoa(encodeURIComponent(str)))
            codeBlock.setAttribute('data-lang', lang)
          }
        }, 0)

        return `<div class="code-block" id="${id}">
                  <div class="code-header">
                    <span class="code-lang">${lang}</span>
                    <div class="code-actions">
                      <button class="action-btn copy-btn">
                        <span class="btn-icon">📋</span>
                        复制
                      </button>
                      <button class="action-btn download-btn">
                        <span class="btn-icon">⬇️</span>
                        下载
                      </button>
                    </div>
                  </div>
                  <pre class="hljs"><code>${highlighted}</code></pre>
                </div>`
      } catch (__) {}
    }
    return `<pre class="hljs"><code>${md.utils.escapeHtml(str)}</code></pre>`
  }
})

const renderedContent = computed(() => {
  return md.render(props.content)
})

// 处理复制和下载事件
const setupCodeBlockHandlers = () => {
  // 复制功能
  const clipboard = new Clipboard('.copy-btn', {
    text: function(trigger) {
      const codeBlock = trigger.closest('.code-block')
      if (!codeBlock) return ''
      const encodedCode = codeBlock.getAttribute('data-code')
      if (!encodedCode) return ''
      try {
        // 解码存储的代码内容
        return decodeURIComponent(atob(encodedCode))
      } catch (e) {
        console.error('解码失败:', e)
        return ''
      }
    }
  })
  
  clipboard.on('success', (e) => {
    const btn = e.trigger as HTMLButtonElement
    btn.innerHTML = '<span class="btn-icon">✅</span>已复制'
    setTimeout(() => {
      btn.innerHTML = '<span class="btn-icon">📋</span>复制'
    }, 2000)
    e.clearSelection()
  })

  clipboard.on('error', () => {
    console.error('复制失败')
  })

  // 下载功能
  document.querySelectorAll('.download-btn').forEach(btn => {
    btn.addEventListener('click', (e) => {
      const codeBlock = (e.currentTarget as HTMLElement).closest('.code-block')
      if (!codeBlock) return

      const encodedCode = codeBlock.getAttribute('data-code')
      const lang = codeBlock.getAttribute('data-lang')
      if (!encodedCode || !lang) return

      try {
        // 解码存储的代码内容
        const code = decodeURIComponent(atob(encodedCode))
        const blob = new Blob([code], { type: 'text/plain' })
        const url = window.URL.createObjectURL(blob)
        const a = document.createElement('a')
        const timestamp = new Date().getTime()
        let extension = lang || 'txt'
        
        // 根据语言确定文件扩展名
        switch (lang.toLowerCase()) {
          case 'javascript':
          case 'js':
            extension = 'js'
            break
          case 'typescript':
          case 'ts':
            extension = 'ts'
            break
          case 'html':
            extension = 'html'
            break
          case 'css':
            extension = 'css'
            break
          case 'scss':
            extension = 'scss'
            break
          case 'json':
            extension = 'json'
            break
          case 'vue':
            extension = 'vue'
            break
        }

        a.href = url
        a.download = `vivian_gpt_${dayjs(timestamp).format('YYYYMMDD')}.${extension}`
        document.body.appendChild(a)
        a.click()
        window.URL.revokeObjectURL(url)
        document.body.removeChild(a)
      } catch (e) {
        console.error('下载失败:', e)
      }
    })
  })
}

onMounted(() => {
  setupCodeBlockHandlers()
})

// 监听内容变化，重新设置事件处理程序
watch(() => props.content, () => {
  nextTick(() => {
    setupCodeBlockHandlers()
  })
})
</script>

<style lang="scss">
.markdown-content {
  font-size: 16px;
  line-height: 1.6;
  word-wrap: break-word;

  h1, h2, h3, h4, h5, h6 {
    margin-top: 24px;
    margin-bottom: 16px;
    font-weight: 600;
    line-height: 1.25;
  }

  p {
    margin-bottom: 16px;
  }

  ul, ol {
    padding-left: 2em;
    margin-bottom: 16px;
  }

  table {
    width: 100%;
    margin-bottom: 16px;
    border-collapse: collapse;

    th, td {
      padding: 8px;
      border: 1px solid var(--border-color);
    }

    th {
      background-color: var(--bg-secondary);
      font-weight: 600;
    }

    tr:nth-child(even) {
      background-color: var(--bg-secondary);
    }
  }

  .code-block {
    margin-bottom: 16px;
    border-radius: 6px;
    overflow: hidden;
    background: #282c34;

    .code-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 8px 16px;
      background: #21252b;
      color: #abb2bf;

      .code-lang {
        font-family: monospace;
        font-size: 0.9em;
      }

      .code-actions {
        display: flex;
        gap: 8px;
      }

      .action-btn {
        display: flex;
        align-items: center;
        gap: 4px;
        padding: 4px 8px;
        font-size: 12px;
        color: #abb2bf;
        background: #353b45;
        border: none;
        border-radius: 4px;
        cursor: pointer;
        transition: all 0.3s ease;

        .btn-icon {
          font-size: 14px;
        }

        &:hover {
          background: #3e4451;
        }
      }
    }

    pre {
      margin: 0;
      padding: 16px;
      overflow-x: auto;

      code {
        font-family: 'Fira Code', monospace;
        font-size: 14px;
        line-height: 1.5;
      }
    }
  }

  blockquote {
    padding: 0 1em;
    color: var(--text-secondary);
    border-left: 0.25em solid var(--border-color);
    margin-bottom: 16px;
  }

  img {
    max-width: 100%;
    height: auto;
  }
}

// 深色主题适配
:root.dark {
  .markdown-content {
    table {
      th {
        background-color: var(--bg-secondary);
      }
    }

    blockquote {
      border-left-color: var(--border-color);
    }
  }
}
</style>